package com.nanbei.a17;

import com.nanbei.a15.A15;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.aspectj.AspectJPointcutAdvisor;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;

/**
 * @ClassDescription:
 * @JdkVersion: 1.8
 * @Author: libs
 * @Created: 2024/11/19 15:02
 */
public class A17 {
    public static void main(String[] args) {
        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("aspectJ",AspectJ.class);
        context.registerBean("advisorConfig",AdvisorConfig.class);
        context.registerBean(ConfigurationClassPostProcessor.class);
        context.registerBean(AnnotationAwareAspectJAutoProxyCreator.class);
        context.refresh();

        String[] beanNames = context.getBeanDefinitionNames();



        for (String beanName : beanNames) {
            System.out.println(beanName);
        }

    }


    static class Target1 {
        public void foo() {
            System.out.println("target1 foo");
        }
    }

    static class Target2 {
        public void bar() {
            System.out.println("target2 bar");
        }
    }

    @Aspect
    static class AspectJ{

        @Before("execution(* foo(*))")
        public void before(){
            System.out.println("AspectJ before...");
        }

        @After("execution(* foo(*))")
        public void after(){
            System.out.println("AspectJ after...");
        }
    }


    @Configuration
    static class AdvisorConfig{
        // 创建切面
        @Bean
        public Advisor advisor(MethodInterceptor advice){
            // 设置切入点
            AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
            pointcut.setExpression("execution(* foo(*))");
            return new DefaultPointcutAdvisor(pointcut,advice);
        }

        // 创建通知
        @Bean
        public MethodInterceptor advice(){
            return invocation -> {
                System.out.println("Advisor before...");
                Object proceed = invocation.proceed();
                System.out.println("Advisor after...");
                return proceed;
            };
        }
    }
}
